package com.stylefeng.guns.core.util.appSecure;

import java.math.BigInteger;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.RSAPrivateKeySpec;
import java.security.spec.RSAPublicKeySpec;
import java.security.spec.X509EncodedKeySpec;

import javax.crypto.Cipher;

import com.stylefeng.guns.core.util.appSecure.encoder.BASE64Decoder;


//http://blog.csdn.net/scape1989/article/details/18959657
public class RSAUtil {

	// protected static String privateEncode =
	// "0a73b4debe33b4f4c541d1cacdf2b4cdefe5a2268b2ca3232f1766cbf91ef718f449e7c01d9a32e3cf84486e0c6dd74ba4d3425454cdf28ad6349d7efefb8dbe1f680497b71faf14622fdb9221cdc631824fa14963bfe870c2c6310ac059202a103b04ec4d09442648ab9020301000102818027b451f5e92220fad8c788ec94180cf0a6331d43f6f087f0169ef7ffcaf559fbe0bd761b0db61dc8afe4d1bcdd9381fb827e6ee0036db33b90c1dc6f76ca3442ff7b688514a8450434f7122826a278c67f85a78ac2f878442f0d32e05649be113401faf1d31548333e503f02a29990fc2946dbd321e65bcfcb5ea9352859607d024100d8d45db47da4b0464f582b7bf5a9b8e1f0b59e65508822cc7080bb78bf3333db119c3cac0222b34345cd680b560ae23f0706d64dfe83e8d500354bd2a681b3b3024100a1d6a12c59036279b2556a0159779fc419eea2814481d28f97f59a50ee1072ad15a89a28fcf956773e136656e2233d24e924f27fbf8832fb0951921c105781e30240714294e3e7d173c67641af0d2428908b6cc9e1c0384db427a8088664af3316be32b7b2b582b40f816f5fb91e5ac67aa1c390ddb685e0ef68fb9fdb48607355a3024036e3e8fe75a264400a7055e7e7445f77cfa3d4922b7e2cc06f35ea0510f99b2b817111f85cf4e492c507276ac8805338b5aac664f5bd682d24d7f9ca72f07b29024100bcc8d1468fc76ad87a71478599e0cc84f565ceeeded2270e792b1126a0a736d9123f376efdf531d763819e6781761e3f7310c8e039636ee7e58eece208b5b2df";
	// protected static String publicEncode =
	// "0c3601738bcde48415e89628ba62a2c07097b8dbe081d87c49e7e9b0c3fbc0245d88e5ad1e764083625006cf7921918b404518c9a5b436d3b05bea9afb01e1dc9822d160d436cb5419ae6000e6f8e085dd446983532b0203010001";
 
	// 公钥
	public static final String publicEncode=   
		"" + "\r" +  
	    "" + "\r" +  
	    "" + "\r" +  
	    "" + "\r";
	
	// 私钥
	public static final String privateEncode= 
		"" + "\r" +  
	    "" + "\r" +  
	    "" + "\r" +  
	    "" + "\r" +  
	    
	    "" + "\r" +  
	    "" + "\r" +  
	    "" + "\r" +  
	    "" + "\r" +  
	    
	    "" + "\r" +  
	    "" + "\r" +  
	    "" + "\r" +  
	    "" + "\r" +  
	   
	    "" + "\r" +  
	    "" + "\r";
		    
	/** 移动端的安全包名 */
	public static String appId = "com.yyw.test"; // 移动端的安全包名(移动端提供)

	/** uuid */
	public static String token = "d9bb999a-7674-4234-8f22-51f09094067a"; // uuid :d9bb999a-7674-4234-8f22-51f09094067a

	/** 签名算法 */
	public static final String SIGN_ALGORITHMS = "MD5withRSA";

	public static byte[] encrypt(byte[] bytes) {
		try {
			//System.out.println(publicEncode.toCharArray());
			BASE64Decoder decoder = new BASE64Decoder();
			byte[] pubData = decoder.decodeBuffer(publicEncode);
			RSAPublicKey publicKey = getPublicKey(pubData);
			return encrypt(publicKey, bytes);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return bytes;
	}

	public static byte[] decrypt(byte[] bytes) {
		try {
			BASE64Decoder decoder = new BASE64Decoder();
			byte[] privateData = decoder.decodeBuffer(privateEncode);
			RSAPrivateKey privateKey = getPrivateKey(privateData);
			// RSAPrivateKey privateKey = getRSAPrivateKey(bytes);
			return decrypt(privateKey, bytes);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return bytes;
	}

	//获取签名guangtao
	public static byte[] sign(byte[] bytes) {
		try {
			BASE64Decoder decoder = new BASE64Decoder();
			byte[] privateData = decoder.decodeBuffer(privateEncode);
			RSAPrivateKey privateKey = getPrivateKey(privateData);

			Signature signature = Signature.getInstance("MD5withRSA");
			signature.initSign(privateKey);
			signature.update(bytes);
			return signature.sign();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return new byte[0];
	}

	/*
	 * yyw 返回 RSAPrivateKey
	 */
	public static RSAPrivateKey getRSAPrivateKey(byte[] bytes) {
		try {
			RSAPrivateKey privateKey = getPrivateKey(bytes);
			return privateKey;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	public static RSAPublicKey getPublicKey(byte[] keyBytes) throws Exception {

		X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
		KeyFactory keyFactory = KeyFactory.getInstance("RSA");
		return (RSAPublicKey) keyFactory.generatePublic(keySpec);
	}

	public static RSAPrivateKey getPrivateKey(byte[] keyBytes) throws Exception {
		PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
		KeyFactory keyFactory = KeyFactory.getInstance("RSA");
		return (RSAPrivateKey) keyFactory.generatePrivate(keySpec);
	}

	protected static byte[] encrypt(PublicKey publicKey, byte[] bytes) {
		if (publicKey != null) {
			try {
			//	Cipher cipher = Cipher.getInstance("RSA/ECB/NoPadding"); //安卓
				Cipher cipher = Cipher.getInstance("RSA");
				cipher.init(Cipher.ENCRYPT_MODE, publicKey);
				return cipher.doFinal(bytes);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return bytes;

	}

	protected static byte[] decrypt(PrivateKey privateKey, byte[] bytes) {
		if (privateKey != null) {
			try {
				//Cipher cipher = Cipher.getInstance("RSA"); //安卓
				Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); //java
				cipher.init(Cipher.DECRYPT_MODE, privateKey);
				return cipher.doFinal(bytes);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return bytes;
	}

	@Deprecated
	protected static PublicKey getPublicKey(String modulus,
			String publicExponent) throws Exception {
		BigInteger bigIntModulus = new BigInteger(modulus);
		BigInteger bigIntPublicExponent = new BigInteger(publicExponent);
		RSAPublicKeySpec keySpec = new RSAPublicKeySpec(bigIntModulus,
				bigIntPublicExponent);
		KeyFactory keyFactory = KeyFactory.getInstance("RSA");
		return keyFactory.generatePublic(keySpec);
	}

	@Deprecated
	protected static PrivateKey getPrivateKey(String modulus,
			String privateExponent) throws Exception {
		BigInteger bigIntModulus = new BigInteger(modulus);
		BigInteger bigIntPrivateExponent = new BigInteger(privateExponent);
		RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(bigIntModulus,
				bigIntPrivateExponent);
		KeyFactory keyFactory = KeyFactory.getInstance("RSA");
		return keyFactory.generatePrivate(keySpec);
	}

	public static String bytesToString(byte[] bytes) {
		return new String(bytes);
	}
}
